<?php
// +----------------------------------------------------------------------
// | zhanshop-marketing / ActionServer.php    [ 2024/12/18 14:56 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2024 zhangqiquan All rights reserved.
// +----------------------------------------------------------------------
// | Author: zhangqiquan <768617998@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\api\admin\v1\service;

use app\provider\AdEventUploadProvider;
use zhanshop\App;

class ActionService
{
    /**
     * 获取设备信息
     * @param array $deviceInfo
     * @return array
     */
    protected function getDeviceInfo(array $deviceInfo)
    {
        $deviceUniqueKey = [
            "app" => $deviceInfo["app"],
            "oaid" => $deviceInfo["oaid"],
            "imei" => $deviceInfo["imei"],
            "android_id" => $deviceInfo["android_id"],
            "idfa" => $deviceInfo["idfa"],
            'iddi' => $deviceInfo["iddi"],
            "mac" => $deviceInfo["mac"],
            "ua" => $deviceInfo["ua"],
            "brand" => strtolower($deviceInfo["brand"]),
            "unit_type" => strtolower($deviceInfo["unit_type"]),
            "ipv4" => $deviceInfo["ipv4"],
            "ipv6" => $deviceInfo["ipv6"],
        ];
        $infoKey = 'device:info:'.sha1(json_encode($deviceUniqueKey));
        $device = App::cache()->get($infoKey);
        if($device){
            return json_decode($device, true);
        }
        $device = App::database()->model('visit_device')->search($deviceInfo);
        if($device){
            App::cache()->set($infoKey, json_encode($device), 1800);
        }
        return $device;
    }

    /**
     * 设备启动
     * @param array $deviceInfo
     * @return array
     */
    public function start(array $deviceInfo, string $page, string $param, string $user_id)
    {
        $time = time();
        $device = $this->getDeviceInfo($deviceInfo);

        $isfirst = 0;
        // 去注册设备
        if($device === []){
            list($aduid, $platform) = App::make(AdEventUploadProvider::class)->upload($deviceInfo['app'], 'all', 'activate', [
                'oaid' => $deviceInfo['oaid'],
                'imei' => $deviceInfo['imei'],
                'android_id' => $deviceInfo['android_id'],
                'idfa' => $deviceInfo['idfa'],
                'iddi' => $deviceInfo['iddi'],
                'mac' => $deviceInfo['mac'],
                'ua' => $deviceInfo['ua'],
                'brand' => $deviceInfo['brand'],
                'unit_type' => $deviceInfo['unit_type'],
                'ipv4' => $deviceInfo['ipv4'],
                'ipv6' => $deviceInfo['ipv6'],
            ]);
            $deviceInfo['up_aid'] = $aduid;
            $deviceInfo['up_aname'] = $platform;
            $deviceInfo['create_time'] = $time;
            $deviceInfo['update_time'] = $time;
            $deviceInfo['uuid'] = App::database()->model('visit_device')->register($deviceInfo);
            if($aduid){
                App::database()->model("ad_upload")->where(['id' => $aduid])->update(['uuid' => $deviceInfo['uuid']]); // 更新广告绑定
            }
            $isfirst = 1;
            $device = $deviceInfo;
        }else if($device){
            $update = ['channel' => $device['channel'], 'update_time' => $time];
            if($device['ua']){
                $update['ua'] = $device['ua'];
            }
            if($device['osver']){
                $update['osver'] = $device['osver'];
            }
            if($device['serial']){
                $update['serial'] = $device['serial'];
            }
            App::database()->model('visit_device')->where(['uuid' => $device['uuid']])->update($update);
        }
        if($device){
            try {
                App::database()->model("visit_start")->insert([
                    'app' => $device['app'],
                    'uuid' => $device['uuid'],
                    'guid' => $device['guid'],
                    'is_first' => $isfirst,
                    'up_aid' => $device['up_aid'],
                    'channel' => $device['channel'],
                    'device_info' => json_encode($device),
                    'create_time' => $time
                ]);
                App::database()->model("visit_page")->insert([
                    'app' => $device['app'],
                    'guid' => $device['guid'],
                    'uuid' => $device['uuid'],
                    'is_start' => 1,
                    'is_exit' => 0,
                    'user_id' => $user_id,
                    'version' => $device['version'],
                    'page' => $page,
                    'param' => $param,
                    'start_time' => microtime(true),
                    'end_time' => 0,
                    'channel' => $device['channel'],
                    'up_aid' => $device['up_aid'],
                    'create_time' => $time,
                    'update_time' => $time,
                ]);
            }catch (\Throwable $err){
                if(strpos($err->getMessage(), "1062") !== false){
                    App::error()->setError("启动记录写入失败");
                }else{
                    App::error()->setError($err->getMessage());
                }
            }
        }
        return $device;
    }

    /**
     * 页面开始访问
     * @param array $device
     * @param string $page
     * @param string $param
     * @param int $isStart
     * @param string $userId
     * @return void
     */
    public function startPv(array $device, string $page, string $param, int $isStart, string $userId = "0")
    {
        $time = time();
        $device = $this->getDeviceInfo($device);
        if($device){
            $upAid = 0;
            App::database()->model("visit_page")->insert([
                'app' => $device['app'],
                'guid' => $device['guid'],
                'uuid' => $device['uuid'],
                'is_start' => $isStart,
                'is_exit' => 0,
                'user_id' => $userId,
                'version' => $device['version'],
                'page' => $page,
                'param' => $param,
                'start_time' => microtime(true),
                'end_time' => 0,
                'channel' => $device['channel'],
                'up_aid' => $upAid,
                'create_time' => $time,
                'update_time' => $time,
            ]);
        }
    }

    /**
     * 页面结束访问
     * @param array $device
     * @param string $page
     * @param string $param
     * @param int $isExit
     * @param string $userId
     * @return void
     */
    public function endPv(array $device, string $page, string $param, int $isExit, string $userId = "0")
    {
        $time = time();
        $device = $this->getDeviceInfo($device);
        if($device){
            $id = App::database()->model("visit_page")->where(['uuid' => $device['uuid'], 'guid' => $device['guid'], 'page' =>  $page, 'param' => $param])->order('id desc')->value('id');
            if($id){
                App::database()->model("visit_page")->where(['id' => $id])->update([
                    'is_exit' => $isExit,
                    'end_time' => microtime(true),
                    'update_time' => $time,
                ]);
            }
        }
    }

    /**
     * 注册
     * @param array $device
     * @param $userId
     * @return void
     */
    public function register(array $device, $userId)
    {
        $device = $this->getDeviceInfo($device);
        if($device){
            list($aduid, $platform) = App::make(AdEventUploadProvider::class)->upload($device['app'], 'all', 'register', [
                'uuid' => $device['uuid']
            ], [
                'user_id' => $userId,
            ]);
            $time = time();
            App::database()->model("visit_register")->insert([
                'app' => $device['app'],
                'guid' => $device['guid'],
                'uuid' => $device['uuid'],
                'user_id' => $userId,
                'up_aid' => $aduid,
                'channel' => $device['channel'],
                'create_time' => $time,
            ]);

            App::database()->model('visit_device')->where(['uuid' => $device['uuid']])->update(['user_id' => $userId, 'update_time' => $time]);
            return [
                'user_id' => $userId,
                'uuid' => $device['uuid']
            ];
        }
        return [
            'user_id' => $userId,
            'uuid' => 0
        ];
    }

    /**
     * 下单
     * @param array $device
     * @param $userId
     * @param $orderId
     * @param string $payWay
     * @param float $amount
     * @return void
     */
    public function order(array $device, $userId, $orderId, string $payWay, float $amount = -1)
    {
        $device = $this->getDeviceInfo($device);

        if($device){
            list($aduid, $platform) = App::make(AdEventUploadProvider::class)->upload($device['app'], 'all', 'order', [
                'uuid' => $device['uuid']
            ], [
                'order_id' => $orderId,
                'user_id' => $userId,
                'pay_way' => $payWay,
                'amount' => $amount,
            ]);

            App::database()->model("visit_order")->insert([
                'app' => $device['app'],
                'guid' => $device['guid'],
                'uuid' => $device['uuid'],
                'user_id' => $userId,
                'order_id' => $orderId,
                'pay_way' => $payWay,
                'amount' => $amount,
                'order_info' => '',
                'up_aid' => $aduid,
                'channel' => $device['channel'],
                'create_time' => time(),
            ]);
        }
    }

    /**
     * 支付
     * @param array $device
     * @param $userId
     * @param $orderId
     * @param string $payWay
     * @param float $amount
     * @return void
     */
    public function pay(array $device, $userId, $orderId, string $payWay, float $amount = -1)
    {
        $device = $this->getDeviceInfo($device);
        if($device){
            list($aduid, $platform) = App::make(AdEventUploadProvider::class)->upload($device['app'], 'all', 'pay', [
                'uuid' => $device['uuid']
            ], [
                'order_id' => $orderId,
                'user_id' => $userId,
                'pay_way' => $payWay,
                'amount' => $amount,
            ]);

            App::database()->model("visit_pay")->insert([
                'app' => $device['app'],
                'guid' => $device['guid'],
                'uuid' => $device['uuid'],
                'user_id' => $userId,
                'order_id' => $orderId,
                'pay_way' => $payWay,
                'amount' => $amount,
                'order_info' => '',
                'up_aid' => $aduid,
                'channel' => $device['channel'],
                'create_time' => time(),
            ]);
        }
    }
}